package com.yueke.yuekeshop.shopweb.service.impl;



import com.yueke.common.core.exception.WoniuException;
import com.yueke.yuekeshop.shopmodel.dto.orders.UserGoodOrdersDto;
import com.yueke.yuekeshop.shopmodel.params.car.GoodsCarParams;
import com.yueke.yuekeshop.shopweb.service.ShopCarService;
import com.yueke.yuekeshop.shopweb.service.ShopOrdersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;

@Service
@Slf4j
public class ShopCarServiceImpl implements ShopCarService {


    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private ShopOrdersService shopOrdersService;

    /**
     * 添加购物车 :userId:1
     * @param goodsCarParams
     */
    @Override
    public void addOrdersCar(GoodsCarParams goodsCarParams) {
        Integer userId=1;
        Set<String> campsiteList = stringRedisTemplate.opsForZSet().range("campsite:ids", 0, -1);
        List<String> goodsOnIds = this.getGoodsOnIds(campsiteList);
        System.out.println(goodsOnIds);
        boolean isContainsOn = goodsOnIds.contains(goodsCarParams.getGoodsId()+"");
        if (!isContainsOn){
            throw new WoniuException(404,"商品或已失效");
        }
        Set<String> carIds = stringRedisTemplate.opsForZSet().range("car:ids:userId:" + userId, 0, -1);
        boolean isContains = carIds.contains(goodsCarParams.getGoodsId()+"");
        if (isContains){
            stringRedisTemplate.opsForHash().increment("userId:"+userId+":id:"+goodsCarParams.getGoodsId(),"goodsOrdersCount",goodsCarParams.getGoodsOrdersCount());
        }else {
            HashMap<String, String> map = getNamValMap(goodsCarParams);
            stringRedisTemplate.opsForHash().putAll("userId:"+userId+":id:"+goodsCarParams.getGoodsId(),map);
            stringRedisTemplate.opsForZSet().add("car:ids:userId:"+userId,goodsCarParams.getGoodsId()+"",System.currentTimeMillis());
        }

    }

    /**
     * 抽取需要营地上架商品ids集合
     * @param campsiteList
     * @return
     */
    private List<String> getGoodsOnIds(Set<String> campsiteList) {
        List<String>  goodsOnIds = new ArrayList<>();
        campsiteList.forEach(campsiteId ->{
            Set<String> goodsIds = stringRedisTemplate.opsForZSet().range("campsite:" + campsiteId+ ":goods:on:ids", 0, -1);
            goodsOnIds.addAll(goodsIds);
            Collections.reverse(goodsOnIds); /* 控制输出顺序的地方 */
        });
        return goodsOnIds;
    }

    /**
     * 抽取需要营地未上架商品ids集合
     * @param campsiteList
     * @return
     */
    private List<String>  getGoodsDownIds(Set<String> campsiteList) {
        List<String>  goodsOnIds = new ArrayList<>();
        campsiteList.forEach(campsiteId ->{
            Set<String> goodsIds = stringRedisTemplate.opsForZSet().range("campsite:" + campsiteId+ ":goods:ids", 0, -1);
            goodsIds.removeAll(this.getGoodsOnIds(campsiteList));
            goodsOnIds.addAll(goodsIds);  /* 控制输出顺序的地方 */
            Collections.reverse(goodsOnIds);
        });
        return goodsOnIds;
    }


    /**
     *  把对象转化成map
     * @param obj
     * @return
     */
    public HashMap<String, String> getNamValMap(Object obj) {
        HashMap<String, String> map = new HashMap<>();
        Field[] fieldArr = obj.getClass().getDeclaredFields();
        try {
            for (Field field : fieldArr) {
                field.setAccessible(true);
                if (field.get(obj) != null && !"".equals(field.get(obj).toString())) {
                    map.put(field.getName(), field.get(obj).toString());
                }
            }
        } catch (IllegalAccessException e) {
            log.error(e.getMessage());
        }
        return map;
    }

    /**
     * 删除购物车商品
     * @param goodsId
     */
    @Override
    public void deleteOrdersCar(Integer goodsId) {
        Integer userId=1;
        stringRedisTemplate.opsForZSet().remove("car:ids:userId:"+userId,goodsId+"");
        stringRedisTemplate.delete(("userId:"+userId+":id:"+goodsId));
    }

    /**
     * 自增购物车商品数量
     * @param goodsId
     */
    @Override
    public void incrementOrdersCarCount(Integer goodsId) {
        Set<String> campsiteList = stringRedisTemplate.opsForZSet().range("campsite:ids", 0, -1);
        List<String> goodsOnIds = this.getGoodsOnIds(campsiteList);
        System.out.println(goodsOnIds);
        boolean isContainsOn = goodsOnIds.contains(goodsId+"");
        if (!isContainsOn){
            throw new WoniuException(404,"商品或已失效");
        }
        Integer userId=1;
        stringRedisTemplate.opsForHash().increment("userId:"+userId+":id:"+goodsId,"goodsOrdersCount",1);
    }

    /**
     * 自减购物车商品数量
     * @param goodsId
     */
    @Override
    public void decrementOrdersCarCount(Integer goodsId) {
        Set<String> campsiteList = stringRedisTemplate.opsForZSet().range("campsite:ids", 0, -1);
        List<String> goodsOnIds = this.getGoodsOnIds(campsiteList);
        System.out.println(goodsOnIds);
        boolean isContainsOn = goodsOnIds.contains(goodsId+"");
        if (!isContainsOn){
            throw new WoniuException(404,"商品或已失效");
        }
        Integer userId=1;
        stringRedisTemplate.opsForHash().increment("userId:"+userId+":id:"+goodsId,"goodsOrdersCount",-1);
    }

    /**
     * 立即购买
     * @param goodsCarParams
     * @return
     */
    @Override
    public UserGoodOrdersDto payOrdersCar(GoodsCarParams goodsCarParams) {
        this.addOrdersCar(goodsCarParams);
        List<String> goodsIds = new ArrayList<>();
        goodsIds.add(goodsCarParams.getGoodsId()+"");
        UserGoodOrdersDto userGoodOrdersDto = shopOrdersService.addGoodsOrder(goodsIds);
        return userGoodOrdersDto;
    }
}
